/**
 * Copyright (C) 2017-2018 pinganfang, Inc. All Rights Reserved.
 */
package com.pingan.haofang.searchcloud.solr.api;

import com.pingan.haofang.searchcloud.api.IndexDataPacket;
import com.pingan.haofang.searchcloud.api.IndexDataPushService;
import com.pingan.haofang.searchcloud.api.IndexRowData;
import com.pingan.haofang.searchcloud.api.constants.EngineType;
import com.pingan.haofang.searchcloud.api.route.IndexRoute;
import com.pingan.haofang.searchcloud.api.route.IndexRouteRegisterFactory;
import com.pingan.haofang.searchcloud.solr.api.client.SolrClientFactory;
import com.pingan.haofang.searchcloud.solr.constants.SolrConstant;
import org.apache.commons.collections.CollectionUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author huhailiang937
 * @date 2017年5月5日下午1:58:27
 * @since 1.0.0
 */
@Service("solrIndexDataPushService")
public class SolrIndexDataPushService implements IndexDataPushService {

    protected static Logger LOG = LoggerFactory.getLogger(SolrIndexDataPushService.class);


    @Autowired
    SolrClientFactory clientFactory;

    @Override
    public boolean repository(String host, IndexDataPacket indexDataPacket, int millisecondTimeOut, boolean needRoute) {

        if (LOG.isDebugEnabled()) {
            LOG.debug(">>repository,params:indexDataPacket{}, needRoute", indexDataPacket);
        }

        // 1、从数据包中获取 索引名称
        String indexName = indexDataPacket.getIndexName();

        // 2、根据索引名称获取 存储层数据落地的索引
        String enableIndexName = indexDataPacket.getIndexName();


        try {
            CloudSolrClient solrClient = clientFactory.getByHost(host);
            if (needRoute) {
                IndexRoute route = IndexRouteRegisterFactory.get().discover(indexName);
                enableIndexName = route.getCollectionName();
            }

            DocumentIndexRowDataBinder rowDataBinder = new DocumentIndexRowDataBinder();

            // 3.1、更新数据
            List<IndexRowData> updateDatas = indexDataPacket.getUpdateData();
            if (CollectionUtils.isNotEmpty(updateDatas)) {
                List<SolrInputDocument> docs = rowDataBinder.toSolrInputDocuments(updateDatas);
                solrClient.add(enableIndexName, docs);
                LOG.info(String.format("SolrIndex add index:(%s)  size:(%d)", enableIndexName, docs.size()));
            }

            // 3.2、删除数据
            List<IndexRowData> deleteDatas = indexDataPacket.getDeleteData();
            if (CollectionUtils.isNotEmpty(deleteDatas)) {
                List<String> ids = rowDataBinder.toSolrDocumentIds(deleteDatas);
                solrClient.deleteById(enableIndexName, ids);
                LOG.info(String.format("SolrIndex delete index:(%s)  size:(%d)", enableIndexName, ids.size()));
            }
            return true;
        } catch (Exception e) {
            LOG.error(String.format("SolrIndexDataPacketService repository[%s] data has error:", enableIndexName), e);

            /**
             * https://issues.apache.org/jira/browse/SOLR-4783<br>
             * https://issues.apache.org/jira/browse/SOLR-4895 <br>
             * And maybe rollback should fail if auto-commit or commitWithin are<br>
             * configured or the latter is explicitly used on update requests or<br>
             * in update documents.<br>
             */

            // try {
            // solrClient.rollback(enableIndexName);
            // } catch (SolrServerException e1) {
            // LOG.error(String.format("SolrIndexDataPacketService
            // repository[%s] data has SolrServerException:",
            // enableIndexName), e);
            // } catch (IOException e1) {
            // LOG.error(String.format("SolrIndexDataPacketService
            // repository[%s] data has IOException:",
            // enableIndexName), e);
            // }
            throw new RuntimeException(e);
        }

    }

    /**
     * 获取索引指定字段 最大值
     *
     * @param host
     * @param indexName
     * @param versionField
     * @return 整形的返回值
     */
    @Override
    public Long getMaxValue(String host, String indexName, String versionField) {
        CloudSolrClient solrClient = clientFactory.getByHost(host);
        SolrQuery query = new SolrQuery();
        query.setQuery("*:*");
        query.setFields(versionField);
        query.setSort(versionField, SolrQuery.ORDER.desc);
        query.setStart(0);
        query.setRows(1);
        QueryResponse response = null;
        try {
            response = solrClient.query(SolrConstant.ALIAS_PREFIX + indexName, query);
        } catch (Exception e) {
            LOG.error("solr inc get max version value failed,indexName:{}",indexName);
            e.printStackTrace();
            return null;
        }
        SolrDocumentList results = response.getResults();
        if(results.size() == 0){
            return 0L;
        }
        SolrDocument entries = results.get(0);
        Long aLong = (Long) entries.get(versionField);
        return aLong == null ? 0 : aLong;
    }

    @Override
    public EngineType getEngineType() {
        return EngineType.SOLR;
    }
}
